package emulator.unittest.hardware;

import static org.junit.Assert.*;
import org.junit.Test;

import emulator.hardware.HwByte;

public class HwByteTest {

	@Test
	public void testInit() {
		HwByte b = new HwByte();
		assertEquals(0, b.getNumber());
	}


	@Test
	public void testAdd() {
		HwByte b = new HwByte();
		b.add(HwByte.create(0x7F));
		assertEquals(0x7F, b.getNumber());
		
		b.add(HwByte.create(0x80));
		assertEquals(0xFF, b.getNumber());
		
		b.add(HwByte.create(0x01));
		assertEquals(0x00, b.getNumber());
	}

	@Test
	public void testSub() {
		HwByte b = new HwByte();
		b.sub(HwByte.create(0x7F));
		assertEquals(0x81, b.getNumber());
		
		b.sub(HwByte.create(0x80));
		assertEquals(0x01, b.getNumber());
		
		b.sub(HwByte.create(0x01));
		assertEquals(0x00, b.getNumber());
	}

	@Test
	public void testMul() {
		HwByte b = new HwByte();
		b.mul(HwByte.create(0x01));
		assertEquals(0x00, b.getNumber());
		
		b.setNumber(0x15);
		b.mul(HwByte.create(0x00));
		assertEquals(0x00, b.getNumber());
		
		b.setNumber(0x15);
		b.mul(HwByte.create(0x03));
		assertEquals(0x3F, b.getNumber());

		b.mul(HwByte.create(0x10));
		assertEquals(0xF0, b.getNumber());
	}

	@Test
	public void testDiv() {
		HwByte b = new HwByte();
		b.div(HwByte.create(0x01));
		assertEquals(0x00, b.getNumber());
		
		b.setNumber(0xA5);
		b.div(HwByte.create(0x3E));
		assertEquals(0x02, b.getNumber());
		
		b.div(HwByte.create(0x02));
		assertEquals(0x01, b.getNumber());

		b.div(HwByte.create(0x02));
		assertEquals(0x00, b.getNumber());
	}

	@Test(expected=ArithmeticException.class)
	public void testDivZero() {
		HwByte b = new HwByte();
		b.setNumber(0x15);
		b.div(HwByte.create(0x00));
		assertEquals(0x00, b.getNumber());
	}

	@Test
	public void testNot() {
		HwByte b = new HwByte();
		b.not();
		assertEquals(0xFF, b.getNumber());
	}

	@Test
	public void testAnd() {
		HwByte b = new HwByte();
		b.setNumber(0x3E);
		b.and(HwByte.create(0x11));
		assertEquals(0x10, b.getNumber());
	}

	@Test
	public void testOr() {
		HwByte b = new HwByte();
		b.setNumber(0x3E);
		b.or(HwByte.create(0x11));
		assertEquals(0x3F, b.getNumber());
	}

	@Test
	public void testXor() {
		HwByte b = new HwByte();
		b.setNumber(0x3E);
		b.xor(HwByte.create(0x11));
		assertEquals(0x2F, b.getNumber());
	}

	@Test
	public void testShift() {
		HwByte b = new HwByte();
		b.shift(5);
		assertEquals(0, b.getNumber());
		
		b.setNumber(0x32);
		b.shift(0);
		assertEquals(0x32, b.getNumber());
		
		b.shift(2);
		assertEquals(0xC8, b.getNumber());

		b.shift(-4);
		assertEquals(0x0C, b.getNumber());

		b.shift(5);
		assertEquals(0x80, b.getNumber());
	}

	@Test
	public void testIsGreaterThan() {
		HwByte b = new HwByte();
		assertFalse(b.isGreaterThan(HwByte.create(0x7F)));
		assertFalse(b.isGreaterThan(HwByte.create(0x93)));
		b.setNumber(0x7F);
		assertFalse(b.isGreaterThan(HwByte.create(0x7F)));
		assertFalse(b.isGreaterThan(HwByte.create(0x93)));
		b.setNumber(0x80);
		assertTrue(b.isGreaterThan(HwByte.create(0x7F)));
		assertFalse(b.isGreaterThan(HwByte.create(0x93)));
		b.setNumber(0xAF);
		assertTrue(b.isGreaterThan(HwByte.create(0x7F)));
		assertTrue(b.isGreaterThan(HwByte.create(0x93)));
	}

	@Test
	public void testIsEqualTo() {
		HwByte b = new HwByte();
		b.setNumber(0x03);
		assertFalse(b.isEqualTo(HwByte.create(0x00)));
		assertTrue(b.isEqualTo(HwByte.create(0x03)));
		assertFalse(b.isEqualTo(HwByte.create(0x7F)));
	}

	@Test
	public void testIsLessThan() {
		HwByte b = new HwByte();
		assertTrue(b.isLessThan(HwByte.create(0x7F)));
		assertTrue(b.isLessThan(HwByte.create(0x93)));
		b.setNumber(0x7F);
		assertFalse(b.isLessThan(HwByte.create(0x7F)));
		assertTrue(b.isLessThan(HwByte.create(0x93)));
		b.setNumber(0x80);
		assertFalse(b.isLessThan(HwByte.create(0x7F)));
		assertTrue(b.isLessThan(HwByte.create(0x93)));
		b.setNumber(0xAF);
		assertFalse(b.isLessThan(HwByte.create(0x7F)));
		assertFalse(b.isLessThan(HwByte.create(0x93)));
	}

	@Test
	public void testSetBit() {
		HwByte b = new HwByte();
		b.setBit(0, true);
		assertEquals(0x01, b.getNumber());
		b.setBit(5, true);
		assertEquals(0x21, b.getNumber());
		b.setBit(0, false);
		assertEquals(0x20, b.getNumber());
	}

	@Test
	public void testGetBit() {
		HwByte b = new HwByte(0x37);
		assertTrue(b.getBit(0));
		assertTrue(b.getBit(1));
		assertTrue(b.getBit(2));
		assertFalse(b.getBit(3));
		assertTrue(b.getBit(4));
		assertTrue(b.getBit(5));
		assertFalse(b.getBit(6));
		assertFalse(b.getBit(7));
		assertFalse(b.getBit(8));
	}
}
